<template>
  <div class="graph">
    <svg class="svgContainer"></svg>
    <div class="g-search">
      <el-pagination
        :current-page="tableModule.currentPage"
        :page-size="tableModule.pageSize"
        :pager-count="1"
        :small="true"
        background
        layout=" prev, pager, next"
        :total="tableModule.count"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
      <!-- <el-form ref="ruleFormRef" :rules="rules" :inline="true" :model="ruleForm" class="demo-form-inline search">
        <el-form-item label="实体名称" :label-width="formLabelWidth" prop="entityName">
          <el-autocomplete style="   z-index: 999999 !important;
      position: absolute;" v-model="ruleForm.entityName" :fetch-suggestions="querySearch" :trigger-on-focus="false"
            clearable class="inline-input w-50" placeholder="请输入实体名称" @select="onSubmit(ruleFormRef)" />
        </el-form-item>
      </el-form> -->
    </div>
    <div class="g-left-circular-top-box">
      <span>新增实体</span>
      <!-- <fieldset> -->
      <!-- <legend>新增实体</legend> -->
      <!-- </fieldset> -->
    </div>
    <div class="g-left">
      <span>关联同级实体</span>
      <!-- <fieldset> -->
      <!-- <legend>关联同级实体</legend> -->
      <!-- </fieldset> -->
    </div>
    <div class="g-right" v-show="formVisible">
      <el-card shadow="hover">
        <el-form :model="form">
          <el-form-item label="所属图谱">
            <el-input v-model="form.graphName" disabled />
          </el-form-item>
          <el-form-item label="起始节点">
            <el-input v-model="form.startEntity" disabled />
          </el-form-item>
          <el-form-item label="实体关系">
            <el-select
              v-model="form.relation"
              placeholder="请选择实体关系"
              clearable
              filterable
              allow-create
            >
              <!-- <el-option v-for="(item, index) in relationArray" :key="index" :label="item.label" :value="item.value" /> -->
              <el-option
                v-for="(item, index) in relationArray"
                :key="index"
                :label="item"
                :value="item"
              />
              <!-- <el-option label="职业职务" value="职业职务" />
              <el-option label="组织单位" value="组织单位" /> -->
            </el-select>
          </el-form-item>
          <el-form-item label="终止节点">
            <el-input v-model="form.endEntity" clearable />
          </el-form-item>
          <el-form-item label="是否发布">
            <el-switch @click="handleSwitch" v-model="form.featureReleaseStatus" />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="determine()">确定</el-button>
            <el-button @click="cancel()">取消</el-button>
          </el-form-item>
        </el-form>
      </el-card>
    </div>
  </div>
</template>
<script lang="ts" setup>
import * as FormApi from '@/api/knowledge/character'
import * as d3 from 'd3'
import { onMounted } from 'vue'
import type { FormInstance, FormRules, Column } from 'element-plus'
import { useRouter, useRoute } from 'vue-router'
import characterImg from '@/assets/imgs/character.png'
import characterFocusImg from '@/assets/imgs/character-focus.png'
import positionImg from '@/assets/imgs/position.png'
import positionFocusImg from '@/assets/imgs/position-focus.png'
import locationImg from '@/assets/imgs/location.png'
import locationFocusImg from '@/assets/imgs/location-focus.png'
import { useAppStore } from '@/store/modules/app'
const router = useRouter()
const route = useRoute()
const appStore = useAppStore()
appStore.setFooter(false) // 配置当前页面不显示底部版权信息
const selectValue = ref<string>('1')
const inputSearch = ref('')
const formLabelWidth = '80px'
const form = reactive({
  graphName: String(route.query.graphName),
  graphId: route.query.graphId,
  startEntity: '',
  startEntityId: '',
  relation: '',
  endEntity: '',
  endEntityId: '',
  featureReleaseStatus: ''
})
const relationArray = reactive([
  // { label: '', value: '', },
])
const featureReleaseStatus = '0'
const formVisible = ref(false)
const tableData = [] // 图谱数据
const ruleFormRef = ref<FormInstance>()

interface RestaurantItem {
  value: string
  link: string
}
const rules = reactive<FormRules<RuleForm>>({
  entityName: [{ required: false, message: '请输入实体名称', trigger: 'change' }]
})
interface RuleForm {
  entityName: string
}
const ruleForm = reactive<RuleForm>({
  entityName: '',
  desc: '',
  place: '',
  inputSearch: '',
  eventDate: ''
})
const restaurants = ref<RestaurantItem[]>([])
const restaurantsArray = reactive({}) // 自动补全数据源
const querySearch = (queryString: string, cb: any) => {
  const results = queryString
    ? restaurants.value.filter(createFilter(queryString))
    : restaurants.value
  cb(results)

  console.log('restaurants', restaurants)
}
const createFilter = (queryString: string) => {
  return (restaurant: RestaurantItem) => {
    return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
  }
}
// 可视化关系维护-实体关系
const getRelationArray = () => {
  const params = {}
  FormApi.getGraphOptionRelationName(params).then((res) => {
    // console.log('resresresres', JSON.stringify(res))
    console.log('resresresres', res)
    Object.assign(relationArray, res)
    // formVisible.value = true
  })
}
// 分页：pageSize 改变时会触发
const handleSizeChange = (val: number) => {
  tableModule.pageSize = val
  getTableData2(1)
}
// 分页：currentPage 改变时会触发
const handleCurrentChange = (val: number) => {
  tableModule.currentPage = val
  getTableData2(1)
}
// 搜索
const onSubmit = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate((valid, fields) => {
    if (valid) getTableData2(1)
    else console.log('error submit!', fields)
  })
}
// watch(
//   () => form.featureReleaseStatus,
//   (newValue, oldValue) => {
//     handleRelease(form.featureReleaseStatus)
//     resettingDOM()
//     getTableData('featureReleaseStatus')
//   },
//   // { immediate: true, deep: true }
// )
const handleSwitch = () => {
  handleRelease(form.featureReleaseStatus)
  resettingDOM()
}
onMounted(() => {
  getTableData('onMounted')
  getTableData2(1)
  getRelationArray()
})
// 发布
const handleRelease = (type: boolean) => {
  console.log('发布')
  const params = {
    featureCode: form.endEntityId,
    graphName: route.query.graphName,
    featureReleaseStatus: '0' // 0取消发布 1发布
  }
  if (type) params.featureReleaseStatus = '1'
  else params.featureReleaseStatus = '0'
  FormApi.updateFeatureReleaseStatusByFeatureCode(params).then((res) =>
    getTableData('handleRelease')
  )
}
const loadAll = (total) => {
  console.log('调用了loadAll')
  const params = {
    graphId: route.query.graphId,
    entityType: 1, // tabs状态：1 人物图谱 2 事件图谱 3 地点图谱 4 时间图谱
    pageNo: 1,
    pageSize: total
  }
  // if (!restaurantsArray) {
  Object.assign(params, { entityName: ruleForm.entityName })
  FormApi.getGraphEntityPage(params).then((res) => {
    res.list.map((item) => (item.value = item.entityName))
    Object.assign(restaurantsArray, res.list)
    // restaurantsArray = res.
    Object.assign(restaurants.value, restaurantsArray)
    // restaurants.value = restaurantsArray
  })
  // }
}
// 表格数据
const tableModule = reactive({
  tableData: [], // 表格数据
  currentPage: 1, // 表格分页：当前页
  pageSize: 10, // 表格分页：每页显示条目个数
  count: 1 // 表格分页：总记录数
})
const getTableData2 = (entityType) => {
  console.log('entityType', entityType)
  return new Promise((resolve, reject) => {
    try {
      const params = {
        graphId: route.query.graphId,
        // releaseStatus: 0, // 发布状态：0未发布 1已发布
        entityType: 1, // tabs状态：1 人物图谱 2 事件图谱 3 地点图谱 4 时间图谱
        // entityType: entityType, // tabs状态：1 人物图谱 2 事件图谱 3 地点图谱 4 时间图谱
        pageNo: tableModule.currentPage,
        pageSize: tableModule.pageSize
      }
      Object.assign(params, { entityName: ruleForm.entityName })
      FormApi.getGraphEntityPage(params).then((res) => {
        // resettingDOM()
        resettingDOM2()
        res.list.map((item) => {
          item.entityType = 'person'
          item.url = characterImg
        })
        tableModule.tableData = res.list
        tableModule.count = res.total
        loadAll(res.total)
        chart2()
        resolve(res)
      })
    } catch {
      reject()
    } finally {
      console.log('getTableData')
      console.log('Promise执行完毕')
    }
  })
}

const getTableData = (operationStatus) => {
  const params = {
    graphName: String(route.query.graphName),
    entity: route.query.entity
  }
  FormApi.findNeo4jByEntity(params).then((res) => {
    Object.assign(tableData, res)
    init(tableData)
    chart()
    if (operationStatus === 'addData') {
      formVisible.value = true
      Object.keys(form).map((item) => (form[item] = tableData[0][item]))
      form.graphName = String(route.query.graphName)
      form.graphId = route.query.graphId
    }
  })
}

const determine = () => {
  if (form.endEntityId) editData()
  else addData('determine', 'person')
  formVisible.value = false
}
const cancel = () => {
  formVisible.value = false
}
const addData = (operationStatus, entityType) => {
  const params = [
    {
      graphName: String(route.query.graphName),
      entity: route.query.entity,
      relation: '请选择节点关系',
      feature: '',
      entityType: entityType // person 人物 event 事件
    }
  ]
  if (operationStatus === 'determine') params[0].feature = form.endEntity
  else if (operationStatus === 'drag') params[0].feature = '请输入终止节点'
  else if (operationStatus === 'dragCorrelation') params[0].feature = operationalData.entityName
  FormApi.insertNeo4j(params).then((res) => {
    if (res.data === 0) return
    ElMessage({
      message: '新增成功',
      grouping: true,
      showClose: true,
      type: 'success'
    })
    resettingDOM()
    resettingDOM2()
    getTableData('addData')
    getTableData2('addData')
  })
}
const editData = () => {
  const params = [
    {
      graphName: form.graphName, // 所属图谱
      graphId: form.graphId, // 所属图谱ID
      featureCode: form.endEntityId, // 终止节点ID
      newFeature: form.endEntity, // 终止节点名称
      newRelation: form.relation, // 节点关系
      entityCode: form.startEntityId // 起始节点ID
    }
  ]
  FormApi.updateRelationAndFeatureByCode(params).then((res) => {
    if (res.data === 0) return
    ElMessage({
      message: '修改成功',
      grouping: true,
      showClose: true,
      type: 'success'
    })
    resettingDOM()
    getTableData('editData')
    getTableData2('addData')
  })
}

/**
 * @description: 重置销毁g元素，再次初始化，实现数据更新效果
 * @return {*}
 * @author: 叶世超
 */
const resettingDOM = () => {
  let linksText = d3.select(window.document.querySelector('.linksText'))
  let gLeftCircularTop = d3.select(window.document.querySelector('.g-left-circular-top'))
  let gLeftCircularBottom = d3.select(window.document.querySelector('.g-left-circular-bottom'))
  linksText.data([]).exit().remove()
  gLeftCircularTop.data([]).exit().remove()
  // gLeftCircularBottom
  //   .data([])
  //   .exit()
  //   .remove()
}
const resettingDOM2 = () => {
  let gLeftCircularBottom = d3.select(window.document.querySelector('.g-left-circular-bottom'))
  gLeftCircularBottom.data([]).exit().remove()
}
// 图谱数据初始化
function init(ckmData) {
  function genNodesMap(data) {
    const hash = {}
    data.forEach((item) => {
      hash[item.startEntityId] = { id: item.startEntityId, name: item.startEntity, ...item }
      hash[item.endEntityId] = { id: item.endEntityId, name: item.endEntity, ...item }
    })
    return hash
  }
  function genLinks(relations) {
    return relations.map(function ({ startEntityId, endEntityId, relation }) {
      return {
        source: nodesMap[startEntityId],
        target: nodesMap[endEntityId],
        relation,
        value: 1,
        relations: nodesMap[endEntityId].relation
      }
    })
  }
  let svg = d3.select(window.document.querySelector('.svgContainer'))
  let g = svg.append('g')
  // 设置g元素的初始位置
  svg.call(
    d3.zoom().on('zoom', function (current) {
      console.log('current：', current)
      g.attr(
        'transform',
        `translate(${current.transform.x},${current.transform.y}) scale(${current.transform.k})`
      )
    })
  )
  var nodesMap = genNodesMap(ckmData)
  console.log('nodesMap', nodesMap)
  // 构建 links（source 属性必须从 0 开始）
  var edges = genLinks(ckmData)
  console.log('edges', edges)
  // 新建一个力导向图
  let forceSimulation = d3
    .forceSimulation()
    // 使用指定的链接和缺省参数创建新的链接力。如果未指定 links，则默认为空数组。
    .force(
      'link',
      d3.forceLink(edges).distance(function (d) {
        console.log('ddddsss', d)
        // return (d.value + d.index) * 100
        return d.value * 100
      })
    )
    // 正值导致节点相互吸引，类似于重力，而负值导致节点相互排斥，类似于静电荷，默认值-30
    .force('charge', d3.forceManyBody().strength(-200))
    // 创建具有指定 x 和 y 坐标的新中心力。如果未指定 x 和 y，则默认为 ⟨0,0⟩。
    .force('center', d3.forceCenter(750, 300))
  // 生成节点数据
  forceSimulation.nodes(Object.values(nodesMap))
  // 使用 forceCollide 防止节点重叠（节点半径便不会发生重叠，如果有文字，直接直径）
  forceSimulation.force(
    'collide',
    d3
      .forceCollide()
      .radius(function () {
        return 40
      })
      .iterations(1)
  )
  // 箭头
  var arrow = g
    .attr('class', 'arrow')
    .append('g')
    .append('marker')
    .attr('id', 'resolved')
    .attr('markerUnits', 'userSpaceOnUse')
    .attr('viewBox', '0 -5 10 10') // 坐标系的区域
    .attr('refX', 25) // 箭头坐标
    .attr('refY', 0)
    .attr('markerWidth', 10) // 标识的大小
    .attr('markerHeight', 10)
    .attr('orient', 'auto') // 绘制方向，可设定为：auto（自动确认方向）和 角度值
    .attr('stroke-width', 2) // 箭头宽度
    .append('path')
    .attr('d', 'M0,-5L10,0L0,5') // 箭头的路径
    .attr('fill', '#53a0ff') // 箭头颜色
  // 绘制边
  var links = g
    .attr('class', 'lines')
    .append('g')
    .selectAll('path')
    .data(edges)
    .enter()
    .append('path')
    .attr('d', (link) => {
      genLinkPath(link)
    }) // 遍历所有数据。d表示当前遍历到的数据，返回绘制的贝塞尔曲线
    .attr('id', (d, i) => {
      return 'edgepath' + d.id
    }) // 设置id，用于连线文字
    .style('stroke', '#53a0ff') // 颜色
    .style('stroke-width', 2) // 粗细
    .attr('marker-end', 'url(#resolved)') // 根据箭头标记的id号标记箭头
  // 边上的文字
  var linksText = g
    .attr('class', 'linksText')
    .append('g')
    .selectAll('text')
    .data(edges)
    .enter()
    .append('text')
    .attr('x', function (d) {
      return d.source.x
    })
    .attr('y', function (d) {
      return d.source.y
    })
    .text(function (d) {
      return d.relations
    })
    .style('font-size', 10)
    .style('color', 'red')
  // 创建分组
  let gs = g
    .append('g')
    .selectAll('g')
    .data(Object.values(nodesMap))
    .enter()
    .append('g')
    .attr('class', 'singleNode')
    .attr('id', function (d) {
      return 'singleNode' + d.id
    })
    .style('cursor', 'pointer')
    .attr('transform', function (d) {
      return 'translate(' + d.x + ',' + d.y + ')'
    })
  gs.append('image')
    .attr('xlink:href', function (d) {
      console.log(d)
      if (d.endEntityType === 'person') return characterImg
      else if (d.endEntityType === 'event') return positionImg
      else return locationImg
    })
    .attr('x', -20) // 设置图片中心点距离圆心的横向距离
    .attr('y', -20) // 设置图片中心点距离圆心的纵向距离
    .attr('width', 40) // 设置图片的宽度，确保能够填满圆形区域
    .attr('height', 40) // 设置图片的高度，确保能够填满圆形区域
    .attr('clip-path', 'circle(70px at center)') // 使图片在圆形边界内显示
  // 节点悬浮标题
  gs.append('title').text((node) => {
    return node.name
  })
  // 节点底部文字
  gs.append('text')
    .attr('y', 35)
    .attr('text-anchor', 'middle')
    .style('font-size', 13)
    .text(function (d) {
      console.log(d)
      if (d.name.length >= 6) return d.name.substring(0, 6) + '...'
      else return d.name
    })
  // 鼠标交互
  gs.on('mouseover', function (d, i) {
    // console.log(d)
    toggleLineText(d, true)
    toggleLine(links, d, true)
    toggleNode(gs, d, true)
  })
    .on('mouseout', function (d, i) {
      // console.log(d)
      toggleLineText(d, false)
      toggleLine(links, d, false)
      toggleNode(gs, d, false)
    })
    .on(
      'click',
      function (d, i) {
        console.log('ddd', d)
        console.log('iii', i)
        // linksText.style('fill-opacity', function (edge) { if (edge.source === d) return 1 })
        // const element = document.querySelector('.g-right') as HTMLElement
        // element.innerText = d.srcElement.__data__.name
        console.log('d.srcElement.__data__', d.srcElement.__data__)
        Object.keys(form).map((item) => (form[item] = d.srcElement.__data__[item]))
        form.graphName = String(route.query.graphName)
        form.graphId = route.query.graphId
        if (d.srcElement.__data__.featureReleaseStatus === '0') {
          form.featureReleaseStatus = false
        }
        if (d.srcElement.__data__.featureReleaseStatus === '1') {
          form.featureReleaseStatus = true
        }
        // 点击节点为起始节点
        if (d.srcElement.__data__.id === d.srcElement.__data__.startEntityId) {
          form.endEntity = ''
          form.endEntityId = ''
        } else if (d.srcElement.__data__.id === d.srcElement.__data__.endEntityId) {
          // 点击节点为终止节点
        }
        formVisible.value = true
      },
      true
    )
    .call(d3.drag().on('start', started).on('drag', dragged).on('end', ended))
  svg.on(
    'click',
    (event) => {
      console.log(event)
      let data = d3.select(event.srcElement).datum() // 获取事件发生源的数据
      console.log(event.srcElement)
      console.log(data)
      removeSingle()
      const element = document.querySelector('.g-right') as HTMLElement
      // formVisible.value = true
      if (!data) {
        // element.innerText = ''
        formVisible.value = false
      }
    },
    true
  )
  forceSimulation.on('tick', ticked)
  function toggleLineText(currNode, isHover) {
    // if (isHover) {
    //   // 悬浮节点后，文本的高亮显示处理
    //   linksText.style('fill-opacity', function (edge) {
    //     console.log(edge)
    //     console.log(currNode)
    //     if (edge.source.startEntityId === currNode.srcElement.__data__.startEntityId) return 1
    //     else return .1
    //   })
    // } else linksText.style('fill-opacity', function () { return 1 })
    if (isHover) {
      // 悬浮节点后，文本的高亮显示处理
      linksText
        .style('opacity', 0.1)
        .filter((edge) => edge.source.startEntityId === currNode.srcElement.__data__.startEntityId)
        // .filter((edge) => edge.source.startEntityId === currNode.srcElement.__data__.startEntityId)
        .style('opacity', 1)
    } else {
      linksText.style('opacity', 1)
    }
  }
  function toggleLine(linkLine, currNode, isHover) {
    const currNodeData = {}
    Object.assign(currNodeData, currNode.srcElement.__data__)
    console.log(currNodeData)
    if (isHover) {
      // 悬浮节点后，连线的高亮显示处理
      linkLine
        .style('opacity', 0.1)
        // .filter(link => Object.values(link.source).includes(currNodeData.endEntityId))
        // .filter(link => link.source.id === currNodeData.startEntityId)
        .filter((link) => link.target.startEntityId === currNodeData.startEntityId)
        .style('opacity', 1)
      // .classed('link-active', true)
    } else {
      linkLine.style('opacity', 1)
      // .classed('link-active', false)
    }
  }
  /**
   * @description:
   * @param {*} nodeCircle gs组数据
   * @param {*} currNode 当前悬浮节点
   * @param {*} isHover 是否悬浮
   * @return {*}
   * @author: 叶世超
   */
  function toggleNode(nodeCircle, currNode, isHover) {
    console.log(currNode)
    const currNodeData = {} // 当前节点数据
    Object.assign(currNodeData, currNode.srcElement.__data__)
    console.log(currNodeData)
    if (isHover) {
      // 悬浮节点后，节点的高亮显示处理
      nodeCircle
        .style('opacity', 0.1)
        .filter((node) => node.startEntityId === currNodeData.startEntityId)

        // .filter((node) => Object.values(node).includes(currNodeData.id) || Object.values(node).includes(currNodeData.endEntityId) )
        // .filter(node => Object.values(node).includes(currNodeData.id))
        // .filter(node => node.startEntityId === currNodeData.id || node.endEntityId === currNodeData.id)
        .style('opacity', 1)
      // 悬浮切换图片
      if (currNode.srcElement.href) {
        console.log(currNodeData.relation)
        if (currNodeData.endEntityType === 'person')
          currNode.srcElement.href.baseVal = characterFocusImg
        else if (currNodeData.endEntityType === 'event')
          currNode.srcElement.href.baseVal = positionFocusImg
        else currNode.srcElement.href.baseVal = locationFocusImg
      }
    } else {
      nodeCircle.style('opacity', 1)
      if (currNode.srcElement.href) {
        if (currNodeData.endEntityType === 'person') currNode.srcElement.href.baseVal = characterImg
        else if (currNodeData.endEntityType === 'event')
          currNode.srcElement.href.baseVal = positionImg
        else currNode.srcElement.href.baseVal = locationImg
      }
    }
  }
  function removeSingle() {
    d3.select('.singleCircle').remove()
  }
  // 生成关系连线路径
  function genLinkPath(link) {
    // console.log(link)
    let sx = link.source.x
    let tx = link.target.x
    let sy = link.source.y
    let ty = link.target.y
    return 'M' + sx + ',' + sy + ' L' + tx + ',' + ty
  }

  // ticked
  function ticked() {
    // 连线路径
    links.attr('d', (link) => genLinkPath(link))
    // 连线文字位置
    linksText
      .attr('x', function (d) {
        return (d.source.x + d.target.x) / 2
      })
      .attr('y', function (d) {
        return (d.source.y + d.target.y) / 2
      })
    // 节点位置
    gs.attr('transform', function (d) {
      return 'translate(' + d.x + ',' + d.y + ')'
    })
  }
  function started(event, d) {
    // if (!d3.event.active) {
    if (!event.active) {
      forceSimulation.alphaTarget(0.8).restart() // 设置衰减系数，对节点位置移动过程的模拟，数值越高移动越快，数值范围[0, 1]
    }
    // d.fx = d.x
    // d.fy = d.y
    // console.log(event)
    d.fx = event.x
    d.fy = event.y
  }
  function dragged(event, d) {
    // console.log(event)
    // console.log(event.x)
    // console.log(d)
    d.fx = event.x
    d.fy = event.y
    // d.fx = d3.event.x
    // d.fy = d3.event.y
  }
  function ended(event, d) {
    console.log(event)
    console.log(event.active)
    // if (!d3.event.active) {
    if (!event.active) {
      forceSimulation.alphaTarget(0)
    }
    d.fx = null
    d.fy = null
  }
}
const radius = 32
const imageArray = [
  { entityType: 'person', url: characterImg }, // 人物
  { entityType: 'event', url: positionImg } // 事件
  // { entityType:'',url: locationImg }
]
// 左侧拖拽实体初始化
const chart = () => {
  const svg = d3.select(window.document.querySelector('.svgContainer'))
  const svgHeight = window.document.querySelector('.svgContainer')?.clientHeight
  console.log('svgHeight', svgHeight)
  let g = svg.append('g')
  // 创建分组
  let gs = g
    .append('g')
    .attr('class', 'g-left-circular-top')
    .selectAll('.circleText')
    .data(imageArray)
    .enter()
    .append('g')
    .attr('class', 'singleNode')
    .attr('id', function (d) {
      return 'singleNode' + d.id
    })
    // .attr('x', 150)
    .attr('transform', function (d, i) {
      console.log('ddddddddddddddddd', d, i)
      // return 'translate(' + 15 + ',' + (i * radius * 2 + 15) + ')'
      // return 'translate(' + (i * radius * 2 * 2 + 30) + ',' + (50) + ')'
      return 'translate(' + (i * radius * 2 + 18) + ',' + 50 + ')'
      // return 'translate(' + (i * radius * 2 * 2 + 30) + ',' + (svgHeight - 85) + ')'
    })

    // .attr('x', function (d) { return d.source.x })
    // .attr('y', function (d) { return d.source.y })
    .style('cursor', 'pointer')
    .style('zIndex', 999999)
    .style('z-index', 999999)
    .style('zIndex', 999999)
    .style('position', 'relative')
    .call(d3.drag().on('start', dragstarted).on('drag', dragged).on('end', dragended))

  // 节点悬浮标题
  gs.append('title').text((node) => {
    return node.name
  })
  // 节点底部文字
  gs.append('text')
    .attr('x', (radius + 15) / 2)
    .attr('y', radius + 15 + 12)
    .attr('text-anchor', 'middle')
    .style('font-size', 13)
    .text(function (d) {
      console.log('asdfasdf', d)
      return d.entityType
    })
  let gsImage = gs
    .append('image')
    .attr('xlink:href', function (d, i) {
      return d.url
    })
    // .attr('x', 15)
    // .attr('y', function (d, i) { return 15 + i * radius * 2 })
    .attr('width', 50)
    .attr('height', 50)
  // .attr('clip-path', 'circle(70px at center)') // 使图片在圆形边界内显示
  // .call(d3.drag()
  //   .on('start', dragstarted)
  //   .on('drag', dragged)
  //   .on('end', dragended))
  gsImage
    .append('text')
    // .attr('x', 150)
    // .attr('y', 350)
    .attr('text-anchor', 'middle')
    .style('font-size', 130)
    // .style('width', 150)
    // .style('height', 150)
    // .attr('x', function (d) { console.log('ddddddd', d) })
    // .attr('y', function (d) { return d.source.y })
    .text(function (d) {
      // return d.name
      return 'asd'
      // console.log(d)
      // if (d.name.length >= 6) return d.name.substring(0, 6) + '...'
      // else return d.name
    })

  // 拖拽事件处理函数
  function dragstarted(d) {
    d3.select(this).raise().classed('dragging', true)
  }
  function dragged(d, i) {
    console.log('asdf', d, i)
    // 拖拽时初始位置减去图片的半径，即为图片新的位置
    d3.select(this).attr(
      'transform',
      `translate(${d.x - 32},${d.y - 20})`
      // `translate(${d.x},${d.y})`
      // `translate(${d.sourceEvent.x},${d.sourceEvent.y})`
    )
    // .attr('x', d.sourceEvent - 25)
    // .attr('y', d.sourceEvent - 25)
    // .attr('x', d.x - 25)
    // .attr('y', d.y - 25)
  }
  function dragended(d) {
    console.log(d.subject.entityType)
    d3.select(this).classed('dragging', false)
    addData('drag', d.subject.entityType)
  }
  return svg.node()
}
// 左侧拖拽实体初始化
const chart2 = () => {
  const svg = d3.select(window.document.querySelector('.svgContainer'))
  let g = svg.append('g')
  // 创建分组
  let gs = g
    .append('g')
    .attr('class', 'g-left-circular-bottom')
    .selectAll('.circleText')
    .data(tableModule.tableData)
    .enter()
    .append('g')
    .attr('class', 'singleNode')
    .attr('id', function (d) {
      return 'singleNode' + d.id
    })
    .style('cursor', 'pointer')
    .attr('transform', function (d, i) {
      console.log('ddddddddddddddddd', d, i)
      // return 'translate(' + 15 + ',' + (i * radius * 2 + 15 + 60) + ')'
      // return 'translate(' + 15 + ',' + (i * radius * 2 + 15 + 140) + ')'
      return 'translate(' + 50 + ',' + (i * (radius * 2 + 2) + 15 + 140) + ')'
      // return 'translate(' + (i * radius * 2 * 2 + 30) + ',' + 40 + ')'
    })
    .call(d3.drag().on('start', dragstarted).on('drag', dragged).on('end', dragended))

  // 节点悬浮标题
  gs.append('title').text((node) => {
    return node.name
  })
  // 节点底部文字
  gs.append('text')
    .attr('x', (radius + 15) / 2)
    .attr('y', radius + 15 + 12)
    .attr('text-anchor', 'middle')
    .style('font-size', 13)
    .text(function (d) {
      console.log('asdfasdf', d)
      return d.entityName
    })
  gs.append('image')
    .attr('xlink:href', function (d, i) {
      return d.url
    })
    // .attr('x', 15)
    // .attr('y', function (d, i) { return 250 + i * radius * 2 })
    .attr('width', 50)
    .attr('height', 50)
  // .attr('clip-path', 'circle(70px at center)') // 使图片在圆形边界内显示
  // .call(d3.drag()
  //   .on('start', dragstarted)
  //   .on('drag', dragged)
  //   .on('end', dragended))

  // 拖拽事件处理函数
  function dragstarted(d) {
    d3.select(this).raise().classed('dragging', true)
  }
  function dragged(d, i) {
    d3.select(this).attr(
      'transform',
      `translate(${d.x - 32},${d.y - 20})`
      // `translate(${d.x},${d.y})`
      // `translate(${d.sourceEvent.x},${d.sourceEvent.y})`
    )
    // 拖拽时初始位置减去图片的半径，即为图片新的位置
    // d3.select(this)
    //   .attr('x', d.x - 25)
    //   .attr('y', d.y - 25)
  }
  function dragended(d) {
    console.log('ddd', d.subject)
    console.log(d.subject.entityType)
    // operationalData = {}
    Object.assign(operationalData, d.subject)
    d3.select(this).classed('dragging', false)
    addData('dragCorrelation', d.subject.entityType)
  }
  return svg.node()
}
const operationalData = reactive({})
</script>

<style lang="scss" scoped>
.graph {
  height: calc(100vh - 35px - 50px - 4px);
  background-image: url('@/assets/imgs/knowledgegraphBackgroundImage.jpg');
  background-repeat: no-repeat;
}

.svgContainer {
  width: 100%;
  height: 100%;
  // z-index: 999999 !important;
  position: relative !important;
}

.g-search {
  // border: 1px solid red;
  z-index: 999999 !important;
  position: absolute;
  bottom: 10px;
  left: 10px;

  ::v-deep(.el-form) {
    z-index: 999999 !important;
    position: absolute;

    ::v-deep(.el-input) {
      z-index: 999999 !important;
      position: absolute;
    }

    ::v-deep(.el-input__inner) {
      z-index: 999999 !important;
      position: absolute;
    }

    ::v-deep(.el-input__wrapper) {
      z-index: 999999 !important;
      position: absolute;
    }
  }
}

.g-left-circular-top {
  border: 1px solid red !important;
  // z-index: Infinity;
  z-index: 999999 !important;
  position: relative !important;
  /* 添加定位属性 */
}

.g-left-circular-top-box {
  position: absolute;
  top: 20px;
  // left: 10px;
  left: 40px;

  fieldset {
    width: 100px;
    height: 100px;
  }
}

.g-left {
  // width: 300px;
  // height: 500px;
  // z-index: infinity !important;
  position: absolute;
  // bottom: 50px;
  top: 120px;
  left: 30px;

  // z-index: 0;
  span {
    // position: relative;
    // top: 10px;
  }

  // fieldset {
  //   width: 100px;
  //   height: 660px;
  // }
}

// .el-form {
//   z-index: 999999 !important;
//   position: absolute;

//   .el-input {
//     z-index: 999999 !important;
//     position: absolute;
//   }
// }

.g-right {
  // z-index: 9999999 !important;
  // position: relative !important;
  // width: 300px;
  // height: 500px;
  position: absolute;
  top: 10px;
  right: 10px;

  .el-form {
    // z-index: 99999999 !important;
    // position: absolute;

    // .el-input {
    //   z-index: 99999999 !important;
    //   position: absolute;
    // }

    // .el-select {
    //   z-index: 99999999 !important;
    //   position: absolute;
    // }

    // .el-option {
    //   z-index: 99999999 !important;
    //   position: absolute;
    // }
  }
}

legend {
  // background-color: #000;
  // color: #fff;
  text-align: center;
}
</style>
